package cn.kgc.mes.storage.business;

import cn.kgc.mes.storage.domain.MaterialStock;
import cn.kgc.mes.storage.service.IMaterialStockService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import cn.kgc.mes.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import cn.kgc.mes.common.core.plus.dto.common.CommonDataPageResponse;
import cn.kgc.mes.common.core.plus.dto.page.PageDtoRequest;
import cn.kgc.mes.common.core.plus.dto.page.PageDtoResponse;
import cn.kgc.mes.common.core.plus.response.StatusResponse;
import org.springframework.beans.BeanUtils;

import jakarta.annotation.Resource;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.kgc.mes.storage.domain.vo.WmItemRecptLineVo;
import cn.kgc.mes.storage.domain.WmItemRecptLine;
import cn.kgc.mes.storage.service.WmItemRecptLineService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 物料入库单行业务
 * 
 * @author cly
 * @date 2025-09-15
 */
@Component
public class WmItemRecptLineBusiness {

    @Resource
    WmItemRecptLineService settingService;
    @Autowired
    IMaterialStockService materialStockService;

    /**
     * 分页
     *
     * @param vo
     * @return
     */
    public CommonDataPageResponse<WmItemRecptLineVo> page(WmItemRecptLineVo vo) {
        CommonDataPageResponse<WmItemRecptLineVo> response = new CommonDataPageResponse<>();

        //分页
        Long current = 1L;
        Long size = 10L;

        PageDtoRequest reqPageDto = vo.getPageDto();
        if (reqPageDto != null) {
            current = reqPageDto.getCurrent() != null ? reqPageDto.getCurrent() : 1L;
            size = reqPageDto.getSize() != null ? reqPageDto.getSize() : 10L;
        }

        Page page = new Page<>(current, size);

        LambdaQueryWrapper<WmItemRecptLine> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(vo.getRecptId() != null, WmItemRecptLine::getRecptId, vo.getRecptId());

        queryWrapper.eq(StringUtils.hasText(vo.getItemCode()), WmItemRecptLine::getItemCode, vo.getItemCode());

        queryWrapper.like(StringUtils.hasText(vo.getItemName()), WmItemRecptLine::getItemName, vo.getItemName());

        queryWrapper.eq(StringUtils.hasText(vo.getSpecification()), WmItemRecptLine::getSpecification, vo.getSpecification());

        queryWrapper.eq(StringUtils.hasText(vo.getUnitOfMeasure()), WmItemRecptLine::getUnitOfMeasure, vo.getUnitOfMeasure());

        queryWrapper.eq(StringUtils.hasText(vo.getBatchCode()), WmItemRecptLine::getBatchCode, vo.getBatchCode());

        queryWrapper.orderByDesc(WmItemRecptLine::getLineId);

        IPage<WmItemRecptLine> pageRecords = settingService.page(page, queryWrapper);

        //分页记录
        List<WmItemRecptLine> records = pageRecords.getRecords();
        //转为vo
        List<WmItemRecptLineVo> voList = new ArrayList<>();
        for (WmItemRecptLine record : records) {
            WmItemRecptLineVo settingVo  = new WmItemRecptLineVo();

            BeanUtils.copyProperties(record, settingVo);

            voList.add(settingVo);
        }
        response.setRecords(voList);

        //分页信息
        PageDtoResponse pageDto = new PageDtoResponse();
        pageDto.setCurrent(current);
        pageDto.setSize(size);
        pageDto.setTotal(pageRecords.getTotal());
        pageDto.setPages(pageRecords.getPages());

        response.setPageDto(pageDto);

        return response;
    }

    /**
     * 信息
     *
     * @param vo
     * @return
     */
    public WmItemRecptLineVo info(WmItemRecptLineVo vo) {

        WmItemRecptLineVo settingVo = new WmItemRecptLineVo();

        Long lineId = vo.getLineId();

        WmItemRecptLine record = settingService.getById(lineId);

        BeanUtils.copyProperties(record, settingVo);

        return settingVo;
    }

    /**
     * 添加
     *
     * @param vo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public StatusResponse add(WmItemRecptLineVo vo) {
        // 1. 执行添加操作
        StatusResponse response = new StatusResponse();

        WmItemRecptLine record = new WmItemRecptLine();
        BeanUtils.copyProperties(vo, record);
        if (!settingService.save(record)) {
            throw new RuntimeException("添加物料入库单行失败");
        }
        // 2. 执行另一个需要在同一事务中的操作
        LambdaQueryWrapper<MaterialStock> queryWrapper =  new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialStock::getItemId, vo.getItemId())
                .select(MaterialStock::getMaterialStockId, MaterialStock::getItemId, MaterialStock::getItemCode,
                        MaterialStock::getItemName, MaterialStock::getSpecification, MaterialStock::getUnitOfMeasure,
                        MaterialStock ::getQuantityOnhand);
        MaterialStock stock = materialStockService.getOne(queryWrapper);
        if (stock == null) {
            throw new RuntimeException("未找到物料ID为" + vo.getItemId() + "的库存记录");
        }
        // 2.2 计算新库存数量（现有数量 + 接收数量）
        BigDecimal newQuantity = stock.getQuantityOnhand()
                .add(vo.getQuantityRecived() != null ? vo.getQuantityRecived() : BigDecimal.ZERO);

        // 2.3 更新库存信息
        stock.setQuantityOnhand(newQuantity);
        stock.setUpdateTime(new Date()); // 设置修改时间为当前时间

        // 2.4 执行更新，失败则抛出异常触发回滚
        if (!materialStockService.updateById(stock)) {
            throw new RuntimeException("更新物料库存失败");
        }

        // 所有操作成功
        response.setSuccess(true);

        return response;
    }



    /**
     * 更新
     *
     * @param vo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public StatusResponse update(WmItemRecptLineVo vo) {
        StatusResponse response = new StatusResponse();
        LambdaQueryWrapper<WmItemRecptLine> queryWrapper0 = new LambdaQueryWrapper<>();
        queryWrapper0.eq(WmItemRecptLine::getLineId, vo.getLineId()).select(WmItemRecptLine::getItemId, WmItemRecptLine::getItemCode,
                WmItemRecptLine::getItemName,WmItemRecptLine::getQuantityRecived);
        WmItemRecptLine oldRecord = settingService.getOne(queryWrapper0);
        if (oldRecord == null) {
            throw new RuntimeException("未找到入库单明细记录");
        }
        BigDecimal oldQuantity = oldRecord.getQuantityRecived() != null ? oldRecord.getQuantityRecived() : BigDecimal.ZERO;


        //1.操作1,修改物料入库单行信息
        WmItemRecptLine record = new WmItemRecptLine();
        BeanUtils.copyProperties(vo, record);
        if(!settingService.updateById(record)){
            throw new RuntimeException("修改物料入库单行失败");
        }
        //2. 修改该物料的库存现有量
        LambdaQueryWrapper<MaterialStock> queryWrapper =  new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialStock::getItemId, vo.getItemId())
                .select(MaterialStock::getMaterialStockId, MaterialStock::getItemId, MaterialStock::getItemCode,
                        MaterialStock::getItemName, MaterialStock::getSpecification, MaterialStock::getUnitOfMeasure,
                        MaterialStock ::getQuantityOnhand);
        MaterialStock stock = materialStockService.getOne(queryWrapper);
        if (stock == null) {
            throw new RuntimeException("未找到物料ID为" + vo.getItemId() + "的库存记录");
        }
        /// 3.1 计算新库存：现有库存（b） + 新入库数量（c） - 旧入库数量（a）
        BigDecimal currentStock = stock.getQuantityOnhand() != null ? stock.getQuantityOnhand() : BigDecimal.ZERO; // b
        BigDecimal newRecptQuantity = vo.getQuantityRecived() != null ? vo.getQuantityRecived() : BigDecimal.ZERO; // c
        BigDecimal newQuantity = currentStock.add(newRecptQuantity).subtract(oldQuantity); // 修正：使用subtract减去旧数量

        // 3.2 确保库存不为负数（可选，但建议添加）
        if (newQuantity.compareTo(BigDecimal.ZERO) < 0) {
            throw new RuntimeException("库存不足，调整后会出现负数");
        }

        // 3.3 更新库存
        stock.setQuantityOnhand(newQuantity);
        stock.setUpdateTime(new Date());
        if (!materialStockService.updateById(stock)) {
            throw new RuntimeException("更新物料库存失败");
        }


        response.setSuccess(true);
        return response;
    }

    /**
     * 删除
     *
     * @param vo
     * @return
     */
    public StatusResponse delete(WmItemRecptLineVo vo) {
        StatusResponse response = new StatusResponse();

        Long lineId = vo.getLineId();
        if(!settingService.removeById(lineId)){
            throw new RuntimeException("删除物料入库单行失败");
        }

        LambdaQueryWrapper<MaterialStock> queryWrapper =  new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialStock::getItemId, vo.getItemId())
                .select(MaterialStock::getMaterialStockId, MaterialStock::getItemId, MaterialStock::getItemCode,
                        MaterialStock::getItemName,MaterialStock ::getQuantityOnhand);
        MaterialStock stock = materialStockService.getOne(queryWrapper);
        if (stock == null) {
            throw new RuntimeException("未找到物料ID为" + vo.getItemId() + "的库存记录");
        }
        // 2.2 计算新库存数量（现有数量 - 接收数量）
        BigDecimal newQuantity = stock.getQuantityOnhand()
                .subtract(vo.getQuantityRecived() != null ? vo.getQuantityRecived() : BigDecimal.ZERO);

        // 2.3 更新库存信息
        stock.setQuantityOnhand(newQuantity);
        stock.setUpdateTime(new Date()); // 设置修改时间为当前时间

        // 2.4 执行更新，失败则抛出异常触发回滚
        if (!materialStockService.updateById(stock)) {
            throw new RuntimeException("更新物料库存失败");
        }


        response.setSuccess(true);

        return response;
    }

}
